/* 
 * File:   oustream.cpp
 * Author: minaev
 * 
 * Created on 18 Декабрь 2013 г., 15:19
 */

#include "oustream.h"

oustream::oustream(in_addr_t ipaddr_src, uint16_t prt) : streambuf() {
    buf = new char[LENBUF + 1];
    this->saoutUDP.sin_family = PF_INET;
    this->saoutUDP.sin_addr.s_addr = ipaddr_src; //htonl(ipaddr);
    this->saoutUDP.sin_port = htons(prt);

    this->sa.sin_addr.s_addr = htonl(INADDR_ANY);
    this->sa.sin_port = htons(prt + 1);

    udpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    bind(udpSocket, (struct sockaddr*) &(this->sa), sizeof ( struct sockaddr));
    /*int broadcast = 1;
    if (setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST,
            &broadcast, sizeof (broadcast)) == -1) {
        printf("oustream error: udp socket not broacast init!\n");
    }*/
    this->setp(&buf[0], &buf[LENBUF]);
    this->_M_in_cur = &buf[0];

}

oustream::~oustream() {
    this->xsputn(this->_M_out_beg, this->_M_out_cur - this->_M_out_beg);
    close(udpSocket);
    delete [] buf;
}

streamsize oustream::xsputn(const char* __s, uint16_t __n) {
    sendto(udpSocket, __s, __n, 0,
            (struct sockaddr*) &saoutUDP,
            sizeof (struct sockaddr_in));
    return __n;
}

streambuf::int_type oustream::overflow(int_type __c) {
    int_type res;
    buf[LENBUF] = __c;
    res = xsputn(buf, LENBUF + 1) == 0 ? traits_type::eof() : __c;
    this->setp(&buf[0], &buf[LENBUF]);
    this->_M_in_cur = &buf[0];
    return res;
}

/*
 class mystreambuf : public std::streambuf {
protected:
    const int16_t lenbuf = 16;
    char* buf;
    FILE* strmFile;

    streamsize xsputn(const char* __s, uint16_t __n) {
        return fwrite((void*) __s, 1, __n, strmFile);
    }

    int_type overflow(int_type __c) {
        int_type res;
        res = xsputn(buf, lenbuf) == 0 ? traits_type::eof() : __c;
        this->setp(&buf[0], &buf[lenbuf - 1]);
        return res;
    }

public:

    mystreambuf() : streambuf() {
        buf = new char[lenbuf];
        strmFile = fopen("/home/minaev/teststr.txt", "rw+");
        this->setp(&buf[0], &buf[lenbuf - 1]);
    }

    ~mystreambuf() {
        this->xsputn(this->_M_out_beg, this->_M_out_cur - this->_M_out_beg);
        fclose(strmFile);
        delete [] buf;
    }
};
 */
